package cc.ok200.api.common;

import cc.ok200.api.entity.User;
import cc.ok200.api.entity.UserToken;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.HashMap;

/**
 * API请求参数处理类
 * 提供便捷的参数获取和类型转换方法
 */
public class ApiRequest {
    private Map<String, String[]> parameterMap;
    private HttpServletRequest request;

    /**
     * 构造方法，同时接收HttpServletRequest和参数Map
     * @param request HTTP请求对象
     * @param map 额外的参数Map
     */
    public ApiRequest(HttpServletRequest request, Map<String, Object> map) {
        this.request = request;
        this.parameterMap = new HashMap<>();
        
        // 获取请求中的所有参数
        if (request != null && request.getParameterMap() != null) {
            this.parameterMap.putAll(request.getParameterMap());
        }
        
        // 处理额外参数Map中的参数
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if (entry.getValue() != null) {
                    this.parameterMap.put(entry.getKey(), new String[]{entry.getValue().toString()});
                }
            }
        }
    }

    /**
     * 从请求头中获取token，然后查询对应的用户
     * 
     * @return 用户对象
     * @throws ApiException 如果token无效或查询过程中发生任何错误
     */
    public User getUser() throws ApiException {
        try {
            String token = request.getHeader("token");
            if (token == null || token.isEmpty()) {
                throw new ApiException("token_invalid", "缺少token");
            }
            
            UserToken userToken = StaticHolder.userTokenDao.findById(token)
                .orElseThrow(() -> new ApiException("token_invalid", "token无效"));
            
            return StaticHolder.userDao.findById(userToken.userId)
                .orElseThrow(() -> new ApiException("user_not_found", "用户不存在"));
        } catch (ApiException e) {
            throw e;
        } catch (Exception e) {
            throw new ApiException("token_invalid", "登录失效");
        }
    }

    /**
     * 获取字符串参数值
     * @param key 参数名
     * @return 参数值
     * @throws ApiException 如果参数不存在或为空
     */
    public String getString(String key) throws ApiException {
        String value = getStringValue(key);
        if (value == null || value.isEmpty()) {
            throw new ApiException("missing_param", "参数 " + key + " 不能为空");
        }
        return value;
    }

    /**
     * 获取字符串参数值，如果不存在则返回默认值
     * @param key 参数名
     * @param defaultValue 默认值
     * @return 参数值或默认值
     */
    public String getString(String key, String defaultValue) {
        String value = getStringValue(key);
        return (value == null || value.isEmpty()) ? defaultValue : value;
    }

    /**
     * 获取整数参数值
     * @param key 参数名
     * @return 整数参数值
     * @throws ApiException 如果参数不存在或无法转换为整数
     */
    public int getInt(String key) throws ApiException {
        String value = getString(key);
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ApiException("invalid_param", "参数 " + key + " 必须是整数");
        }
    }

    /**
     * 获取整数参数值，如果不存在则返回默认值
     * @param key 参数名
     * @param defaultValue 默认值
     * @return 整数参数值或默认值
     */
    public int getInt(String key, int defaultValue) {
        String value = getStringValue(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取双精度浮点数参数值
     * @param key 参数名
     * @return 双精度浮点数参数值
     * @throws ApiException 如果参数不存在或无法转换为双精度浮点数
     */
    public double getDouble(String key) throws ApiException {
        String value = getString(key);
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            throw new ApiException("invalid_param", "参数 " + key + " 必须是数字");
        }
    }

    /**
     * 获取双精度浮点数参数值，如果不存在则返回默认值
     * @param key 参数名
     * @param defaultValue 默认值
     * @return 双精度浮点数参数值或默认值
     */
    public double getDouble(String key, double defaultValue) {
        String value = getStringValue(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取布尔参数值
     * @param key 参数名
     * @return 布尔参数值
     * @throws ApiException 如果参数不存在
     */
    public boolean getBool(String key) throws ApiException {
        String value = getString(key);
        return isTrueValue(value);
    }

    /**
     * 获取布尔参数值，如果不存在则返回默认值
     * @param key 参数名
     * @param defaultValue 默认值
     * @return 布尔参数值或默认值
     */
    public boolean getBool(String key, boolean defaultValue) {
        String value = getStringValue(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        return isTrueValue(value);
    }
    
    /**
     * 判断字符串是否表示true
     * @param value 字符串值
     * @return 是否为true
     */
    private boolean isTrueValue(String value) {
        return "true".equalsIgnoreCase(value) || "1".equals(value) || 
               "yes".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value);
    }

    /**
     * 获取原始字符串值
     * @param key 参数名
     * @return 字符串值或null
     */
    private String getStringValue(String key) {
        String[] values = parameterMap.get(key);
        if (values == null || values.length == 0) {
            // 如果参数Map中没有，尝试从请求头获取
            return request.getHeader(key);
        }
        return values[0];
    }
} 